package com.alan.camunda.boot.controller;


import com.alan.camunda.boot.dto.CommentVO;
import com.alan.camunda.boot.service.HandlerChoose;
import com.alan.camunda.boot.service.TempUserHolder;
import com.alan.camunda.boot.util.BpmnUtil;
import jakarta.annotation.Resource;
import org.camunda.bpm.engine.HistoryService;
import org.camunda.bpm.engine.IdentityService;
import org.camunda.bpm.engine.RepositoryService;
import org.camunda.bpm.engine.RuntimeService;
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.history.HistoricTaskInstance;
import org.camunda.bpm.engine.task.Comment;
import org.camunda.bpm.engine.task.Task;
import org.camunda.bpm.model.bpmn.BpmnModelInstance;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/tasks")
public class TaskController {
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private HistoryService historyService;
    @Resource
    private TaskService taskService;
    @Resource
    private IdentityService identityService;
    @Resource
    private HandlerChoose handlerChoose;
    @Resource
    private RepositoryService repositoryService;


    @GetMapping("/getHistoryTasks")
    public List<String> getHistoryTasks(String userId) {
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(userId)
                .finished()
                .list();
        return list.stream().map(HistoricTaskInstance::getId).toList();
    }


    @PostMapping("/addComment")
    public String addComment(String taskId, String comment) {
        try {
            // 需要通过 IdentityService 来设置当前用户信息，不能在 createComment 时传入
            identityService.setAuthenticatedUserId("demo");
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            if (task != null) {
                taskService.createComment(taskId, task.getProcessInstanceId(), comment);
            } else {
                return "Task not found";
            }
        } finally {
            identityService.clearAuthentication();
        }
        return "success";
    }

    @PostMapping("/addUser")
    public String addUser(String taskId, String userId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        String activityId = task.getTaskDefinitionKey();

        runtimeService.createProcessInstanceModification(task.getProcessInstanceId())
                .startBeforeActivity(activityId)
                .setVariable("assignee", userId) // 这里配合流程图上指定的变量
                .execute();
        return "success";
    }


    @GetMapping("/getComments")
    public List<CommentVO> getComments(String proInsId) {
        List<Comment> comments = taskService.getProcessInstanceComments(proInsId);

        List<CommentVO> result = comments.stream().map(c -> {
            CommentVO vo = new CommentVO();
            vo.setTaskId(c.getTaskId());
            vo.setUserId(c.getUserId());
            vo.setCreateTime(c.getTime());
            vo.setComment(c.getFullMessage());
            return vo;
        }).toList();

        String[] taskIds =comments.stream().map(Comment::getTaskId).distinct().toList().toArray(new String[0]);

        // 当前任务信息需要通过  TaskService 来查询
        List<Task> tasks = taskService.createTaskQuery().taskIdIn(taskIds).list();
        // 历史任务信息需要通过  HistoryService 来查询
        // historyService.createHistoricTaskInstanceQuery();

        return result;
    }

    @PostMapping("/delegateTask")
    public String delegateTask(String taskId, String userId) {
        taskService.delegateTask(taskId, userId);
        return "success";
    }

    @PostMapping("/resolveTask")
    public String resolveTask(String taskId) {
        taskService.resolveTask(taskId);
        return "success";
    }

    @PostMapping("/changeAssignee")
    public String changeAssignee(String taskId, String userId) {
        taskService.setAssignee(taskId, userId);
        return "success";
    }

    @PostMapping("/changeCandidateUsers")
    public String changeCandidateUsers(@RequestBody List<String> candidateUsers) {
        handlerChoose.changeCandidateUsers(candidateUsers);
        return "success";
    }

    @GetMapping("/showCandidateUsers")
    public List<String> showCandidateUsers() {
        return handlerChoose.showCandidateUsers();
    }


    /** AQM 版本的处理方式 */
    @PostMapping("/aqmAddUser")
    public String aqmAddUser(String taskId, String userId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();

        runtimeService.createProcessInstanceModification(task.getProcessInstanceId())
                .startBeforeActivity(task.getTaskDefinitionKey())
                .setVariable("assignee", userId)
                .execute();

        return "success";
    }


    @PostMapping("/testNewAddUser")
    public String testNewAddUser(String taskId, String userId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        taskService.setVariable(taskId, "nrOfCompletedInstances", -1);

        runtimeService.createProcessInstanceModification(task.getProcessInstanceId())
                .startBeforeActivity(task.getTaskDefinitionKey())
                .setVariable("assignee", userId)
                .execute();
        taskService.complete(taskId);
        return "success";
    }


    /** AQM 版本的任务分配模式下做到替换处理人 */
    @PostMapping("/getCompletionCondition")
    public String getCompletionCondition(String taskId ) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();

        // 主动删除老任务
        BpmnModelInstance bmi = repositoryService.getBpmnModelInstance(task.getProcessDefinitionId());
        return BpmnUtil.getCompletionCondition(bmi, task.getTaskDefinitionKey());
    }

    @PostMapping("/testModification")
    public String testModification(String taskId, String userId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        List<String> list = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId())
                .taskDefinitionKey(task.getTaskDefinitionKey())
                .list().stream().map(Task::getAssignee)
                .toList();

        TempUserHolder.setTempUsers(List.of("user1", "user2", "user3", "demo"));
        try {
            runtimeService.createProcessInstanceModification(task.getProcessInstanceId())
                    .cancelAllForActivity(task.getTaskDefinitionKey())
                    .startBeforeActivity("Activity_1tj72i2#multiInstanceBody")
                    .execute();
        } finally {
            TempUserHolder.clear();
        }

        return "success";
    }

    @PostMapping("/modifyReceivedTask")
    public String testModification(String proInsId, String from, String to) {
        try {
            runtimeService.createProcessInstanceModification(proInsId)
                    .cancelAllForActivity(from)
                    .startBeforeActivity(to)
                    .execute();
        } catch (Exception e) {
            e.printStackTrace();
            return "failed";
        }
        return "success";
    }


}
